import {
  _decorator,
  Component,
  input,
  Input,
  Animation,
  Event,
  EventKeyboard,
  Node,
  KeyCode,
  Vec2,
  Vec3,
  Quat,
} from 'cc'
import FSMMgr from '../../Managers/FSMMgr'
import JackDieState from '../State/Jack/JackDieState'
import JackIdleState from '../State/Jack/JackIdleState'
import JackRunState from '../State/Jack/JackRunState'
const { ccclass, property } = _decorator

enum JackState {
  Idle,
  Run,
  Die,
  Attack,
}

enum JackDirection {
  TOP = 'TOP',
  BOTTOM = 'BOTTOM',
  LEFT = 'LEFT',
  RIGHT = 'RIGHT',
}

@ccclass('JackCtrl')
export class JackCtrl extends Component {
  anim: Animation
  fsmMgr: FSMMgr
  x: number = 0
  y: number = 0
  targetX: number = 0
  targetY: number = 0
  private scaleX: number = 1
  private scaleY: number = 1
  private up = false
  private down = false
  private left = false
  private right = false
  private actions: Array<KeyCode> = []
  private readonly speed = 50

  start() {
    this.anim = this.getComponent(Animation)
    this.fsmMgr = new FSMMgr()

    let idle = new JackIdleState(JackState.Idle, this, this.fsmMgr)
    let run = new JackRunState(JackState.Run, this, this.fsmMgr)
    let die = new JackDieState(JackState.Die, this, this.fsmMgr)

    this.fsmMgr.StateList = [idle, run, die]
    this.fsmMgr.ChangeState(JackState.Idle)

    input.on(Input.EventType.KEY_DOWN, this.onKeyDown, this)
    // input.on(Input.EventType.KEY_PRESSING, this.onKeyDown, this)
    input.on(Input.EventType.KEY_UP, this.onKeyUp, this)
  }

  update(dt: number) {
    if (this.fsmMgr.CurrentIndex != -1) {
      this.fsmMgr.OnUpdate()
    }
    this.updateXY(dt)
  }

  idle() {
    // console.log('[JackCtrl] idle')
    this.fsmMgr.ChangeState(JackState.Idle)
  }

  run() {
    // console.log('[JackCtrl] run')
    this.fsmMgr.ChangeState(JackState.Run)
  }

  die() {
    // console.log('[JackCtrl] die')
    this.fsmMgr.ChangeState(JackState.Die)
  }

  onKeyDown(event: EventKeyboard) {
    this.handleKeyDown(event.keyCode)
  }

  onKeyUp(event: EventKeyboard) {
   this.handleKeyUp(event.keyCode)
  }

  handleKeyDown(code: KeyCode) {
    console.log(code);
    switch (code) {
      case KeyCode.ARROW_RIGHT:
        this.right = true
        break
      case KeyCode.ARROW_LEFT:
        this.left = true
        break
      case KeyCode.ARROW_UP:
        this.up = true
        break
      case KeyCode.ARROW_DOWN:
        this.down = true
        break
    }
    if (this.actions.indexOf(code) === -1) this.actions.push(code)
    this.run()
  }

  handleKeyUp(code: KeyCode) {
    switch (code) {
      case KeyCode.ARROW_RIGHT:
        this.right = false
        break
      case KeyCode.ARROW_LEFT:
        this.left = false
        break
      case KeyCode.ARROW_UP:
        this.up = false
        break
      case KeyCode.ARROW_DOWN:
        this.down = false
        break
    }
    this.actions = this.actions.filter((item) => item != code)
    if (this.actions.length === 0) this.idle()
  }

  onButtonDown(event: Event, code: KeyCode) {
    this.right = this.left = false
    this.actions = []
    this.handleKeyDown(Number(code))
  }

  updateXY(dt: number) {
    if (this.right) {
      this.scaleX = 1
      this.x += this.speed * dt
    } else if (this.left) {
      this.scaleX = -1
      this.x -= this.speed * dt
    }
    if (this.up) {
      this.y += this.speed * dt
    } else if (this.down) {
      this.y -= this.speed * dt
    }
    this.node.setScale(this.scaleX, this.scaleY)
    this.node.setPosition(this.x, this.y)
  }

  // onKeyDown(event: EventKeyboard) {
  //   this.movePostition(this.node, this.speed, event.keyCode)
  // }

  movePostition(node: Node, speed: number, keyCode: KeyCode) {
    let move_cur = new Quat()
    let move_rota = new Vec3()
    node.getRotation(move_cur)
    Quat.toEuler(move_rota, move_cur)
    let posi_cur = new Vec3()
    let posi_target = new Vec3()
    let posi_move = null
    let x: number = speed * 10
    let y: number = speed * 10
    node.getPosition(posi_cur)
    switch (keyCode) {
      case KeyCode.ARROW_RIGHT:
        this.run()
        if (move_rota.y >= 0 && move_rota.y <= 90) {
          posi_move = new Vec3(x, 0, -y)
        } else if (move_rota.y > 90 && move_rota.y <= 180) {
          posi_move = new Vec3(-x, 0, -y)
        } else if (move_rota.y >= -90 && move_rota.y < 0) {
          posi_move = new Vec3(x, 0, y)
        } else if (move_rota.y < -90 && move_rota.y > -180) {
          posi_move = new Vec3(-x, 0, y)
        }
        Vec3.add(posi_target, posi_cur, posi_move)
        node.setPosition(posi_target)
        break
      case KeyCode.ARROW_LEFT:
        if (move_rota.y >= 0 && move_rota.y <= 90) {
          posi_move = new Vec3(-x, 0, y)
        } else if (move_rota.y > 90 && move_rota.y <= 180) {
          posi_move = new Vec3(x, 0, y)
        } else if (move_rota.y >= -90 && move_rota.y < 0) {
          posi_move = new Vec3(-x, 0, -y)
        } else if (move_rota.y < -90 && move_rota.y > -180) {
          posi_move = new Vec3(x, 0, -y)
        }
        Vec3.add(posi_target, posi_cur, posi_move)
        node.setPosition(posi_target)
        break
      case KeyCode.ARROW_UP:
        break
      case KeyCode.ARROW_DOWN:
        break
    }
  }
}
